package com.scs.application.modules.sys.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.scs.application.core.consts.Const;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.query.QueryContext;
import com.scs.application.core.service.BaseServiceImpl;
import com.scs.application.core.service.IBaseFileService;
import com.scs.application.core.utils.BeanUtils;
import com.scs.application.core.utils.FileUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.Tools;
import com.scs.application.modules.sys.dto.DictDTO;
import com.scs.application.modules.sys.entity.DictData;
import com.scs.application.modules.sys.mapper.DictDataMapper;
import com.scs.application.modules.sys.service.DictDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 服务实现类
 * </p>
 */

@Slf4j
@Service
public class FileDictDataServiceImpl extends BaseServiceImpl<DictDataMapper, DictData> implements DictDataService, IBaseFileService {

    @Autowired
    private FileDictTypeServiceImpl fileDictTypeService;

    @Override
    public boolean removeCascadeById(Serializable id) {
        List<DictDTO> dictDTOs = fileDictTypeService.getDTOList();
        for (DictDTO dictDTO : dictDTOs) {
            if (dictDTO.getDictDataDTOS() == null || dictDTO.getDictDataDTOS().isEmpty()) {
                continue;
            }
            for (DictDTO.DictDataDTO dictDataDTO : dictDTO.getDictDataDTOS()) {
                if (id.equals(dictDataDTO.getId())) {
                    dictDTO.getDictDataDTOS().remove(dictDataDTO);
                    String result = JSON.toJSONString(dictDTO, SerializerFeature.PrettyFormat);
                    String fileNameWithPath = Const.DATA_VIEW_DICT_SRC + dictDTO.getCode() + ".json";
                    FileUtils.writeTxtFile(fileNameWithPath, result);
                    break;
                }
            }
        }
        return true;
    }

    @Override
    public DictData getById(Serializable id) {
        List<DictDTO> dictDTOs = fileDictTypeService.getDTOList();
        DictData dictData = new DictData();
        for (DictDTO dictDTO : dictDTOs) {
            if (dictDTO.getDictDataDTOS() == null || dictDTO.getDictDataDTOS().isEmpty()) {
                continue;
            }
            for (DictDTO.DictDataDTO dictDataDTO : dictDTO.getDictDataDTOS()) {
                if (id.equals(dictDataDTO.getId())) {
                    BeanUtils.copyProperties(dictDataDTO, dictData);
                    break;
                }
            }
        }
        return dictData;
    }

    @Override
    public boolean removeCascadeByIds(Collection<? extends Serializable> idList) {
        for (Serializable id : idList) {
            removeCascadeById(id);
        }
        return true;
    }

    @Override
    public Page<DictData> page(QueryContext context) {
        List<DictData> dictDatas = list(context);
        return filePage(context, dictDatas);
    }

    @Override
    public List<DictData> list() {
        QueryContext context = new QueryContext();
        return list(context);
    }

    @Override
    public List<DictData> list(QueryContext context) {
        List<DictDTO> dictDTOS = fileDictTypeService.getDTOList();
        if (dictDTOS == null && dictDTOS.isEmpty()) {
            return null;
        }
        if (context != null && context.getParams() != null && !context.getParams().isEmpty()) {
            String dictTypeId = context.getParams().get("dictTypeId") == null ? "" : context.getParams().get("dictTypeId").toString();
            if (StringUtils.isEmpty(dictTypeId)) {
                return null; //不支持没有传入类型的查询
            }
            Optional<DictDTO> optDict = dictDTOS.stream().filter(dict -> dictTypeId.equals(dict.getId())).findFirst();
            if (optDict.isPresent()) {
                List<DictDTO.DictDataDTO> dictDataDTOS = optDict.get().getDictDataDTOS();
                if (dictDataDTOS == null || dictDataDTOS.isEmpty()) {
                    return null;
                }
                List<DictData> dictDataList = Lists.newArrayListWithCapacity(dictDataDTOS.size());
                for (DictDTO.DictDataDTO dictDataDTO : dictDataDTOS) {
                    DictData dictData = new DictData();
                    BeanUtils.copyProperties(dictDataDTO, dictData);
                    dictDataList.add(dictData);
                }
                return dictDataList;
            }
        } else { //获取所有的
            List<DictData> dictDataList = Lists.newArrayList();
            for (DictDTO dictDTO : dictDTOS) {
                if (dictDTO.getDictDataDTOS() != null && !dictDTO.getDictDataDTOS().isEmpty()) {
                    dictDTO.getDictDataDTOS().forEach(dictDataDTO -> {
                        DictData dictData = new DictData();
                        BeanUtils.copyProperties(dictDataDTO, dictData);
                        dictDataList.add(dictData);
                    });
                }
            }
            return dictDataList;
        }
        return null;
    }

    @Override
    public <DictType> boolean saveBatch(Class<DictType> modelClass, Collection<DictType> entityList, int batchSize) {
        return false;
    }

    @Override
    public boolean saveOrUpdate(DictData dictData) {
        if (dictData == null || StringUtils.isEmpty(dictData.getDictTypeCode())) {
            return false;
        }
        DictDTO dictDTO = fileDictTypeService.getDictDTOByCode(dictData.getDictTypeCode());
        File path = new File(Const.DATA_VIEW_DICT_SRC);
        if (!path.exists()) {
            path.mkdirs();
        }

        if (dictData.getGmtCreate() == null) {
            dictData.setGmtCreate(LocalDateTime.now());
            dictData.setCreator(Tools.getHostName());
        } else {
            dictData.setGmtModified(LocalDateTime.now());
            dictData.setModifier(Tools.getHostName());
        }

        if (dictDTO.getDictDataDTOS() == null || dictDTO.getDictDataDTOS().isEmpty()) {
            dictDTO.setDictDataDTOS(Lists.newArrayList());
        }
        DictDTO.DictDataDTO dictDataDTO = new DictDTO.DictDataDTO();
        if (dictData.getId() == null) {
            dictData.setId(StringUtils.getIdStr());
        }
        BeanUtils.copyProperties(dictData, dictDataDTO);
        dictDTO.getDictDataDTOS().stream().filter(dict -> dictData.getValue().equalsIgnoreCase(dict.getValue())
                && !dictData.getId().equalsIgnoreCase(dict.getId())).findAny().ifPresent(dict -> {
            throw new BusinessException("Key已经存在，请重新命名！");
        });
        dictDTO.getDictDataDTOS().stream().filter(dict -> dictData.getId().equalsIgnoreCase(dict.getId()))
                .findAny().ifPresent(dict -> {
            dictDTO.getDictDataDTOS().remove(dict);
        });

        dictDTO.getDictDataDTOS().add(dictDataDTO);

        String fileNameWithPath = Const.DATA_VIEW_DICT_SRC + dictData.getDictTypeCode() + ".json";
        String result = JSON.toJSONString(dictDTO, SerializerFeature.PrettyFormat);
        FileUtils.writeTxtFile(fileNameWithPath, result);
        return true;
    }


    @Override
    public Boolean isSupport(Boolean flagProject) {
        return !flagProject;
    }
}
